package dataAccess;

import businessEntities.MainLogger;
import businessEntities.QueryResultContainer;
import businessEntities.exceptions.ConnectionException;
import businessEntities.exceptions.QueryException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

public class DALQueryExecutor {

    /**
     * SELECT * FROM 'databaseName'.'tableName'
     * @throws ConnectionException if the connection to the database is not reachable.
     * @throws QueryException for any problem during the executing of the query.
     */
    public QueryResultContainer getWholeTable(String databaseName, String tableName) {

        Connection connection = SingeltonConnection.getConnection();
        String query = "SELECT * FROM " + databaseName + "." + tableName;
        QueryResultContainer result = null;

        try (Statement stm = connection.createStatement()) {

            MainLogger.logger.info("Executing Query : [" + query + "]");
            ResultSet rs = stm.executeQuery(query);
            ResultSetMetaData meta = rs.getMetaData();

            int colCount = meta.getColumnCount();

            //create list and fill the list with the headers
            List<String> headers = new ArrayList<>(colCount);
            for (int c = 1; c <= colCount; c++) {
                headers.add(meta.getColumnName(c));
            }

            //create list of Object[] that represents the table data
            List<String[]> data = new ArrayList<>();
            while (rs.next()) {
                String[] record = new String[colCount];
                for (int i = 0; i < colCount; i++) {
                    record[i] = rs.getString(i + 1);
                }
                data.add(record);
            }

            result = new QueryResultContainer(headers, data);

        } catch (SQLException ex) {
            MainLogger.logger.error("The execution of query : [" + query + "] - FAILED.", ex);
            throw new QueryException("Query: '" + query + "' FAILED", ex);
        }

        return result;
    }

    /**
     * SELECT * FROM 'databaseName'.'tableName' WHERE ...
     * @throws ConnectionException if the connection to the database is not reachable.
     * @throws QueryException for any problem during the executing of the query
     */
    public QueryResultContainer getTableWhere(String dataBaseName, String TableName, String where) {

        Connection connection = SingeltonConnection.getConnection();
        String query = "SELECT * FROM " + dataBaseName + "." + TableName + " WHERE " + where;
        QueryResultContainer result = null;

        try (Statement stm = connection.createStatement()) {

            MainLogger.logger.info("Executing Query : [" + query + "]");
            ResultSet rs = stm.executeQuery(query);
            ResultSetMetaData meta = rs.getMetaData();

            int colCount = meta.getColumnCount();

            //create list and fill the list with the headers
            List<String> headers = new ArrayList<>(colCount);
            for (int c = 1; c <= colCount; c++) {
                headers.add(meta.getColumnName(c));
            }

            //create list of Object[] that represents the table data
            List<String[]> data = new ArrayList<>();
            while (rs.next()) {
                String[] record = new String[colCount];
                for (int i = 0; i < colCount; i++) {
                    record[i] = rs.getString(i + 1);
                }
                data.add(record);
            }

            result = new QueryResultContainer(headers, data);

        } catch (SQLException ex) {
            MainLogger.logger.error("The execution of query : [" + query + "] - FAILED.", ex);
            throw new QueryException("Query: '" + query + "' FAILED", ex);
        }

        return result;
    }
}
